<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <title>Rollup 入门 | liuz2&#39;s Blog</title>
    <meta name="viewport" content="width=device-width,minimum-scale=1">
    <meta name="generator" content="Hugo 0.63.1" />
    
    
      <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
    

    
    
      <link href="/dist/css/app.9576afd3b3c158d98f48ec5df01fec6a.css" rel="stylesheet">
    

    

    
      

    

    

    <meta property="og:title" content="Rollup 入门" />
<meta property="og:description" content="Rollup 是一款轻快的模块打包器。" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://liuz2.gitee.io/posts/rollup-intro/" />
<meta property="article:published_time" content="2021-07-17T11:35:11+08:00" />
<meta property="article:modified_time" content="2021-07-17T11:35:11+08:00" />
<meta itemprop="name" content="Rollup 入门">
<meta itemprop="description" content="Rollup 是一款轻快的模块打包器。">
<meta itemprop="datePublished" content="2021-07-17T11:35:11&#43;08:00" />
<meta itemprop="dateModified" content="2021-07-17T11:35:11&#43;08:00" />
<meta itemprop="wordCount" content="950">



<meta itemprop="keywords" content="rollup," /><meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="Rollup 入门"/>
<meta name="twitter:description" content="Rollup 是一款轻快的模块打包器。"/>

	
  </head>

  <body class="ma0 avenir bg-white">

    
   
  

  <header>
    <div class="bg-black">
      <nav class="pv3 ph3 ph4-ns" role="navigation">
  <div class="flex-l justify-between items-center center">
    <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
      
        liuz2&#39;s Blog
      
    </a>
    <div class="flex-l items-center">
      

      
        <ul class="pl0 mr3">
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/about/" title="About page">
              About
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/links/" title="Links page">
              Links
            </a>
          </li>
          
          <li class="list f5 f4-ns fw4 dib pr3">
            <a class="hover-white no-underline white-90" href="/timeline/" title="Timeline page">
              Timeline
            </a>
          </li>
          
        </ul>
      
      















    </div>
  </div>
</nav>

    </div>
  </header>



    <main class="pb7" role="main">
      
  
  <article class="flex-l flex-wrap justify-between mw8 center ph3">
    <header class="mt4 w-100">
      <h1 class="f3 athelas mt3 mb1">Rollup 入门</h1>
      
      
      <time class="f6 mv1 dib tracked" datetime="2021-07-17T11:35:11&#43;08:00">July 17, 2021</time>

      
      
    </header>
    <div class="nested-copy-line-height lh-copy sans-serif f5 nested-links nested-img mid-gray pr4-l w-two-thirds-l"><p>Rollup 是一款基于 ES 模块的打包器，可用于构建应用或库。与 webpack 相比，它更轻快。</p>
<p>Rollup 的原始作者是 <a href="https://github.com/Rich-Harris">Rich Harris</a>，现在由德国程序员 <a href="https://github.com/lukastaegert">Lukas Taegert-Atkinson</a> 维护。</p>
<p>目前的最新版本是 <code>2.58.0</code>。</p>
<h2 id="安装">安装</h2>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ npm install --global rollup

<span style="color:#75715e"># 查看帮助</span>
$ rollup --help

<span style="color:#75715e"># 查看版本号</span>
$ rollup -v
rollup v2.58.0
</code></pre></div><p>如果要升级 rollup 到最新版，可以使用 <code>npm update -g rollup</code>。</p>
<h2 id="快速上手">快速上手</h2>
<p>简单的配置可以使用命令行打包。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#75715e"># 将入口文件 main.js 打包为 iife 格式</span>
$ rollup main.js --file bundle.js --format iife
<span style="color:#75715e"># CommonJS 格式</span>
$ rollup main.js --file bundle.js --format cjs
<span style="color:#75715e"># UMD 格式</span>
$ rollup main.js --file bundle.js --format umd --name <span style="color:#e6db74">&#34;myBundle&#34;</span>
</code></pre></div><p>其中：</p>
<ul>
<li><code>-o, --file &lt;output&gt;</code> 用于指定输出文件名。若不明确指定输出文件，则默认打印到标准输出，方便调试。</li>
<li><code>-f, --format &lt;format&gt;</code> 设定输出模块类型，可选值有 <code>amd</code>, <code>cjs</code>, <code>es</code>, <code>iife</code>, <code>umd</code>, <code>system</code></li>
<li><code>-n, --name &lt;name&gt;</code> UMD 输出命名</li>
</ul>
<p>由于 Rollup 可以对 ES6 源码静态分析，剔除未使用代码，因此导出的代码很小。这个做法也就是所谓的“Tree Shaking”。</p>
<h2 id="命令行接口">命令行接口</h2>
<p>Rollup 一般通过命令行调用，搭配可选的配置文件，实现常规的打包流程。</p>
<h3 id="配置文件">配置文件</h3>
<p>推荐使用配置文件。配置文件就是一个标准的 ES 模块，通常命名为 <code>rollup.config.js</code>。最简单的配置文件有如下：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> {
    <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;src/main.js&#39;</span>,
    <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> {
        <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;bundle.js&#39;</span>,
        <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
    },
};
</code></pre></div><p>尽管配置文件是 ES 格式，Rollup 打包前会把该文件及其依赖转译为 CommonJS 模块。这样，既可以保证与 Node.js 生态的互操作性，也能使用 ES6 写法编写配置文件。</p>
<p>如果你习惯使用 CommonJS（<code>require</code> 和 <code>module.exports</code>）编写配置文件，可以将配置文件后缀改为 <code>.cjs</code>，这样 Rollup 就不会转译了。另外，如果你使用 Node.js 13+，将后缀改为 <code>.mjs</code>，也能阻止 Rollup 的转译过程。此时，Rollup 将配置文件当作 ES 模块处理。</p>
<p>可以用 TypeScript 等其他语言编写配置文件。为此，安装对应的 Rollup 插件（比如，<code>@rollup/plugin-typescript</code>），并使用 <code>--configPlugin</code> 选项：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ rollup --config rollup.config.ts --configPlugin typescript
</code></pre></div><blockquote>
<p>其中的 <code>--configPlugin &lt;plugin&gt;</code> 指定的插件用于解析配置文件。</p>
</blockquote>
<p>Rollup 的配置格式十分灵活。可以使用数组，同时打包多个不同输入。也可以针对同一个输入，将 <code>output</code> 设定为数组，打包不同的输出格式。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js （设定多个输入输出）
</span><span style="color:#75715e"></span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> [
    {
        <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;main-a.js&#39;</span>,
        <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> {
            <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;dist/bundle-a.js&#39;</span>,
            <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
        },
    },
    {
        <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;main-b.js&#39;</span>,
        <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> [
            {
                <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;dist/bundle-b1.js&#39;</span>,
                <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
            },
            {
                <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;dist/bundle-b2.js&#39;</span>,
                <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;es&#39;</span>,
            },
        ],
    },
];
</code></pre></div><p>如果希望异步创建配置参数，Rollup 可以处理 <code>Promise</code> 的数据。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">fetch</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;node-fetch&#39;</span>;
<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#a6e22e">fetch</span>(
    <span style="color:#e6db74">&#39;/some-remote-service-or-file-which-returns-actual-config&#39;</span>
);
</code></pre></div><p>或者，使用 <code>Promise.all()</code>:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> Promise.<span style="color:#a6e22e">all</span>([<span style="color:#a6e22e">fetch</span>(<span style="color:#e6db74">&#39;get-config-1&#39;</span>), <span style="color:#a6e22e">fetch</span>(<span style="color:#e6db74">&#39;get-config-2&#39;</span>)]);
</code></pre></div><p>使用 <code>-c, --config &lt;filename&gt;</code> 可以指示 Rollup 从配置文件读取参数：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#75715e"># 传入一个自定义配置文件</span>
$ rollup --config my.config.js

<span style="color:#75715e"># 如果不指定文件名称，Rollup 的默认读取顺序如下：</span>
<span style="color:#75715e"># rollup.config.mjs -&gt; rollup.config.cjs -&gt; rollup.config.js</span>
rollup --config
</code></pre></div><p>配置文件还可以导出一个函数。这个函数的返回值就是标准的 Rollup 配置参数，该函数的入参是命令行参数。你可以根据参数动态产生配置参数。甚至可以自定义命令行选项，只需在参数名增加 <code>config</code> 前缀即可：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">defaultConfig</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;./rollup.default.config.js&#39;</span>;
<span style="color:#66d9ef">import</span> <span style="color:#a6e22e">debugConfig</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;./rollup.debug.config.js&#39;</span>;

<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> (<span style="color:#a6e22e">commandLineArgs</span>) =&gt; {
    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">commandLineArgs</span>.<span style="color:#a6e22e">configDebug</span> <span style="color:#f92672">===</span> <span style="color:#66d9ef">true</span>) {
        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">debugConfig</span>;
    }

    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">defaultConfig</span>;
};
</code></pre></div><p>如果执行 <code>rollup --config --configDebug</code>，就会使用 debug 配置文件。</p>
<p>命令行参数的优先级高于配置文件。如果想改变这种默认行为，可以删除 <code>commandLineArgs</code> 中的特定参数：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> (<span style="color:#a6e22e">commandLineArgs</span>) =&gt; {
    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">inputBase</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">commandLineArgs</span>.<span style="color:#a6e22e">input</span> <span style="color:#f92672">||</span> <span style="color:#e6db74">&#39;main.js&#39;</span>;

    <span style="color:#75715e">// 如下操作会让 Rollup 忽略该 CLI 参数
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">delete</span> <span style="color:#a6e22e">commandLineArgs</span>.<span style="color:#a6e22e">input</span>;

    <span style="color:#66d9ef">return</span> {
        <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;src/entries/&#39;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">inputBase</span>,
        <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> { ... },
    };
};
</code></pre></div><h4 id="智能感知">智能感知</h4>
<p>因为 Rollup 自带 TypeScript 类型声明，可以使用 JSDoc 触发 IDE 的智能感知：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#75715e">/**
</span><span style="color:#75715e"> * @type {import(&#39;rollup&#39;).RollupOptions}
</span><span style="color:#75715e"> */</span>
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">config</span> <span style="color:#f92672">=</span> {};
<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#a6e22e">config</span>;
</code></pre></div><p>另外，还可以使用 <code>defineConfig</code> 辅助函数，这样就不需要 JSDoc 文档注释了：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">defineConfig</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;rollup&#39;</span>;

<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#a6e22e">defineConfig</span>({
    <span style="color:#75715e">// ...
</span><span style="color:#75715e"></span>});
</code></pre></div><h3 id="与-javascript-api-的差异">与 JavaScript API 的差异</h3>
<p>配置文件简单，上手容易，但灵活性不够。如果想在其他构建流中使用 Rollup，需要选择 JS API 调用方式。</p>
<p>如果使用 JS API 方式，谨记以下差异：</p>
<ul>
<li>当使用 JS API 时，传入 <code>rollup.rollup</code> 的配置参数类型只能是对象，不能是 Promise 或函数</li>
<li>不能使用数组类型的配置。需要针对每个 <code>inputOptions</code> 执行一次 <code>rollup.rollup</code></li>
<li><code>output</code> 选项会被忽略。你需要为每组 <code>outputOptions</code> 执行一次 <code>bundle.generate(outputOptions)</code> 或 <code>bundle.write(outputOptions)</code></li>
</ul>
<h3 id="从-node-包加载配置文件">从 Node 包加载配置文件</h3>
<p>为了互操作性，Rollup 支持从 <code>node_modules</code> 中安装的包里加载配置文件：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh"><span style="color:#75715e"># 以下命令首先尝试加载 &#34;rollup-config-my-special-config&#34;</span>
<span style="color:#75715e"># 如果加载失败，再加载 &#34;my-special-config&#34;</span>
$ rollup --config node:my-special-config
</code></pre></div><h3 id="命令行标志">命令行标志</h3>
<p>以下是一些常用的命令行标志说明</p>
<p><code>--environment &lt;values&gt;</code></p>
<p>将附加的参数通过 <code>process.env</code> 传入配置文件。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ rollup -c --environment INCLUDE_DEPS,BUILD:production
</code></pre></div><p>会设定 <code>process.env.INCLUDE_DEPS === 'true'</code> 和 <code>process.env.BUILD === 'production'</code>。可以多次使用这个参数，后面的变量会覆盖之前参数。这样，你可以覆盖 <code>package.json</code> 设定的参数：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-json" data-lang="json">{
    <span style="color:#f92672">&#34;scripts&#34;</span>: {
        <span style="color:#f92672">&#34;build&#34;</span>: <span style="color:#e6db74">&#34;rollup -c --environment INCLUDE_DEPS,BUILD:production&#34;</span>
    }
}
</code></pre></div><p>如果像下面这样执行脚本：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ npm run build -- --environment BUILD:development
</code></pre></div><p>那么，配置文件中接收到的参数将是 <code>process.env.INCLUDE_DEPS === 'true'</code> 和 <code>process.env.BUILD === 'development'</code>。</p>
<h3 id="从标准输入读取文件">从标准输入读取文件</h3>
<p>当使用命令行时，Rollup 也支持从标准输入读取内容：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ echo <span style="color:#e6db74">&#34;export const foo = 42;&#34;</span> | rollup --format cjs --file out.js
</code></pre></div><p>如果文件包含 <code>import</code>，Rollup 以当前目录为基础地址，尝试解析相对路径。当使用配置文件时，如果输入文件的名字是 <code>-</code>，Rollup 会将 <code>stdin</code> 作为入口文件。如果要在文件中读取 <code>stdin</code>，只需导入 <code>-</code> 即可，这是 Rollup 内部对于 <code>stdin</code> 的别名。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">foo</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;-&#39;</span>;
</code></pre></div><p>如果传入命令行参数 <code>--no-stdin</code>，Rollup 就会把 <code>-</code> 当作普通文件名处理。</p>
<p>一些插件依赖文件后缀名处理文件，可以通过 <code>--stdin=ext</code> 指定后缀：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ echo <span style="color:#e6db74">&#39;{&#34;foo&#34;: 42, &#34;bar&#34;: &#34;ok&#34;}&#39;</span> | rollup --stdin<span style="color:#f92672">=</span>json -p json
</code></pre></div><p>JS API 总是会把 <code>-</code> 和 <code>-.ext</code> 当作普通文件名称。</p>
<h2 id="javascript-api">JavaScript API</h2>
<p>Rollup 提供的 JavaScript API 可以在 Node.js 中使用。通常你不会使用这个功能，除非要扩展 Rollup 或者动态生成打包资源。</p>
<h3 id="rolluprollup">rollup.rollup</h3>
<p><code>rollup.rollup</code> 函数接收一个输入选项对象，返回 Promise。该 Promise 最终解析为一个 <code>bundle</code> 对象。在这个步骤，Rollup 会<strong>构建模块图，执行摇树算法，但不会产生任何输出</strong>。</p>
<p>在 <code>bundle</code> 对象，可以使用不同的输出选项多次调用 <code>bundle.generate</code>，从而在内存中创建不同的包。如果想直接写入磁盘，使用 <code>bundle.write</code> 即可。</p>
<p>当不需要 <code>bundle</code> 对象时，需要调用 <code>bundle.close()</code>，这会通知所有插件，通过 <code>closeBundle</code> 钩子清理他们的外部进程或服务。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">rollup</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;rollup&#39;</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">path</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;path&#39;</span>);

<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">inputOptions</span> <span style="color:#f92672">=</span> {
    <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;../src/main.js&#39;</span>),
};
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">outputOptions</span> <span style="color:#f92672">=</span> {
    <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;../dist/bundle.js&#39;</span>),
    <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
};

<span style="color:#a6e22e">async</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">build</span>() {
    <span style="color:#75715e">// 构建模块图
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">bundle</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">rollup</span>.<span style="color:#a6e22e">rollup</span>(<span style="color:#a6e22e">inputOptions</span>);

    <span style="color:#75715e">// 在内存中生成打包数据
</span><span style="color:#75715e"></span>    <span style="color:#66d9ef">const</span> { <span style="color:#a6e22e">output</span> } <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">bundle</span>.<span style="color:#a6e22e">generate</span>(<span style="color:#a6e22e">outputOptions</span>);

    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">chunkOrAsset</span> <span style="color:#66d9ef">of</span> <span style="color:#a6e22e">output</span>) {
        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">chunkOrAsset</span>.<span style="color:#a6e22e">type</span> <span style="color:#f92672">===</span> <span style="color:#e6db74">&#39;asset&#39;</span>) {
            <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;asset&#39;</span>, <span style="color:#a6e22e">chunkOrAsset</span>);
        } <span style="color:#66d9ef">else</span> {
            <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">chunkOrAsset</span>.<span style="color:#a6e22e">modules</span>);
        }
    }

    <span style="color:#75715e">// 写入磁盘
</span><span style="color:#75715e"></span>    <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">bundle</span>.<span style="color:#a6e22e">write</span>(<span style="color:#a6e22e">outputOptions</span>);

    <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">bundle</span>.<span style="color:#a6e22e">close</span>();
}

<span style="color:#a6e22e">build</span>();
</code></pre></div><h3 id="rollupwatch">rollup.watch</h3>
<p>Rollup 还提供了 <code>rollup.watch</code> 函数，检测到磁盘模块变化后，自动构建打包。当你在命令行参数使用 <code>--watch</code> 选项，Rollup 会自动调用这个函数。注意，当在 JavaScript API 中使用监听模式时，你需要在 <code>BUNDLE_END</code> 事件中执行 <code>event.result.close()</code>，以便插件在 <code>closeBundle</code> 钩子中清除资源。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">rollup</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;rollup&#39;</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">path</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;path&#39;</span>);

<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">inputOptions</span> <span style="color:#f92672">=</span> {
    <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;../src/main.js&#39;</span>),
};

<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">outputOptions</span> <span style="color:#f92672">=</span> {
    <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;../dist/bundle.js&#39;</span>),
    <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
};

<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">watchOptions</span> <span style="color:#f92672">=</span> {
    ...<span style="color:#a6e22e">inputOptions</span>,
    <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">outputOptions</span>,
    <span style="color:#a6e22e">watch</span><span style="color:#f92672">:</span> {
        <span style="color:#a6e22e">clearScreen</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">true</span>,
        <span style="color:#a6e22e">buildDelay</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">1000</span>,
    },
};

<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">watcher</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">rollup</span>.<span style="color:#a6e22e">watch</span>(<span style="color:#a6e22e">watchOptions</span>);

<span style="color:#a6e22e">watcher</span>.<span style="color:#a6e22e">on</span>(<span style="color:#e6db74">&#39;event&#39;</span>, (<span style="color:#a6e22e">event</span>) =&gt; {
    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">result</span>) {
        <span style="color:#a6e22e">event</span>.<span style="color:#a6e22e">result</span>.<span style="color:#a6e22e">close</span>();
    }
});
</code></pre></div><p>在 <code>event</code> 事件监听器中，<code>event.code</code> 的取值范围如下：</p>
<ul>
<li><code>START</code> 监听器正在开始（重启）</li>
<li><code>BUNDLE_START</code> 开始构建单个包
<ul>
<li><code>event.input</code> 包含输入选项</li>
<li><code>event.output</code> 包含输出选项</li>
</ul>
</li>
<li><code>BUNDLE_END</code> 单个包构建完毕
<ul>
<li><code>event.input</code> 包含输入选项</li>
<li><code>event.output</code> 包含输出选项</li>
<li><code>event.duration</code> 构建持续时间，以毫秒为单位</li>
<li><code>event.result</code> 包含打包对象，可以生成打包文件</li>
</ul>
</li>
<li><code>END</code> 所有包构建完毕</li>
<li><code>ERROR</code> 打包错误
<ul>
<li><code>event.error</code> 包含错误信息</li>
<li><code>event.result</code> 是 <code>null</code> 或打包对象，需要调用 <code>event.result.close()</code> 清理资源</li>
</ul>
</li>
</ul>
<h3 id="动态载入配置文件">动态载入配置文件</h3>
<p>为了方便读取配置文件，Rollup 将命令行读取配置文件的辅助函数也对外暴露。该辅助函数函数接收一个文件路径，以及可选的配置对象。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">rollup</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;rollup&#39;</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">loadConfigFile</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;rollup/dist/loadConfigFile&#39;</span>);
<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">path</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;path&#39;</span>);

<span style="color:#a6e22e">loadConfigFile</span>(<span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#a6e22e">__dirname</span>, <span style="color:#e6db74">&#39;../rollup.config.js&#39;</span>), {
    <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;es&#39;</span>,
}).<span style="color:#a6e22e">then</span>(<span style="color:#a6e22e">async</span> ({ <span style="color:#a6e22e">options</span>, <span style="color:#a6e22e">warnings</span> }) =&gt; {
    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#e6db74">&#39;We currently have %o warnings&#39;</span>, <span style="color:#a6e22e">warnings</span>.<span style="color:#a6e22e">count</span>);
    <span style="color:#a6e22e">warnings</span>.<span style="color:#a6e22e">flush</span>();

    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">const</span> <span style="color:#a6e22e">optionsObj</span> <span style="color:#66d9ef">of</span> <span style="color:#a6e22e">options</span>) {
        <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">bundle</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">await</span> <span style="color:#a6e22e">rollup</span>.<span style="color:#a6e22e">rollup</span>(<span style="color:#a6e22e">optionsObj</span>);
        <span style="color:#a6e22e">await</span> Promise.<span style="color:#a6e22e">all</span>(<span style="color:#a6e22e">optionsObj</span>.<span style="color:#a6e22e">output</span>.<span style="color:#a6e22e">map</span>(<span style="color:#a6e22e">bundle</span>.<span style="color:#a6e22e">write</span>));
    }

    <span style="color:#a6e22e">rollup</span>.<span style="color:#a6e22e">watch</span>(<span style="color:#a6e22e">options</span>);
});
</code></pre></div><h2 id="教程">教程</h2>
<h3 id="使用输出插件">使用输出插件</h3>
<p>一些插件只针对输出。以 <code>rollup-plugin-terser</code> 为例，这是一款用于压缩代码的插件：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ npm i --save-dev rollup-plugin-terser
</code></pre></div><p>下面的配置文件，会生成两个文件包（压缩和未压缩）：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// rollup.config.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">json</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;@rollup/plugin-json&#39;</span>;
<span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">defineConfig</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;rollup&#39;</span>;
<span style="color:#66d9ef">import</span> { <span style="color:#a6e22e">terser</span> } <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;rollup-plugin-terser&#39;</span>;

<span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#a6e22e">defineConfig</span>({
    <span style="color:#a6e22e">input</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;src/main.js&#39;</span>,
    <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> [
        {
            <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;dist/bundle.js&#39;</span>,
            <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;cjs&#39;</span>,
        },
        {
            <span style="color:#a6e22e">file</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;dist/bundle.min.js&#39;</span>,
            <span style="color:#a6e22e">format</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;iife&#39;</span>,
            <span style="color:#a6e22e">name</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;version&#39;</span>,
            <span style="color:#a6e22e">plugins</span><span style="color:#f92672">:</span> [<span style="color:#a6e22e">terser</span>()],
        },
    ],
    <span style="color:#a6e22e">plugins</span><span style="color:#f92672">:</span> [<span style="color:#a6e22e">json</span>()],
});
</code></pre></div><h3 id="代码分割">代码分割</h3>
<p>在动态加载模块（<code>import()</code>）或多入口文件时，Rollup 会进行自动代码拆分。另外，还可以通过 <code>output.manualChunks</code> 手动拆分代码。</p>
<p>为了使用代码分割得到懒加载的效果，可以修改 <code>src/main.js</code> 动态加载 <code>src/foo.js</code>:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-js" data-lang="js"><span style="color:#75715e">// src/main.js
</span><span style="color:#75715e"></span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">default</span> <span style="color:#66d9ef">function</span> () {
    <span style="color:#66d9ef">import</span>(<span style="color:#e6db74">&#39;./foo.js&#39;</span>).<span style="color:#a6e22e">then</span>(({ <span style="color:#66d9ef">default</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">foo</span> }) =&gt; <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">log</span>(<span style="color:#a6e22e">foo</span>));
}
</code></pre></div><p>Rollup 会使用动态加载创建独立的块（chunk），按需加载。为了告知 Rollup 何处放置第二个块，需要使用 <code>--dir</code> 代替 <code>--file</code> 标志位：</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ rollup src/main.js -f cjs -d dist
</code></pre></div><p>这会在 <code>dist</code> 目录创建两个文件，一个是 <code>main.js</code>，另一个是 <code>chunk-[hash].js</code>，其中的 <code>[hash]</code> 表示基于内容的哈希值。你可以通过 <code>output.chunkFileNames</code> 和 <code>output.entryFileNames</code> 选项修改命名规则。</p>
<p>拆分后的应用依然可以运行，只不过速度稍慢，因为只在用到时才去加载解析 <code>./foo.js</code>:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-sh" data-lang="sh">$ node -e <span style="color:#e6db74">&#34;require(&#39;./dist/main.js&#39;)&#34;</span>
</code></pre></div><h2 id="常用插件">常用插件</h2>
<p><a href="https://github.com/rollup/awesome">Awesome Rollup</a> 汇集了常用的优秀插件。</p>
<ul>
<li><a href="https://www.npmjs.com/package/@rollup/plugin-json">@rollup/plugin-json</a> 用于读取 JSON 文件</li>
<li><a href="https://www.npmjs.com/package/@rollup/plugin-typescript">@rollup/plugin-typescript</a> 整合 TypeScript 和 Rollup</li>
<li><a href="https://www.npmjs.com/package/rollup-plugin-terser">rollup-plugin-terser</a> 压缩 es 包</li>
</ul>
<h2 id="ref">REF</h2>
<ol>
<li><a href="https://rollupjs.org/guide/en/">Rollup 官网</a></li>
<li><a href="https://www.npmjs.com/package/rollup">rollup - npm</a></li>
<li><a href="https://github.com/rollup/rollup">rollup/rollup</a> - github</li>
<li><a href="https://survivejs.com/blog/rollup-interview/" title="Rollup - Next-generation ES6 module bundler - Interview with Rich Harris">Rollup - Next-generation ES6 module bundler - Interview with Rich Harris</a>, 2017-07-10</li>
<li><a href="https://nolanlawson.com/2016/08/15/the-cost-of-small-modules/">The cost of small modules</a>, <em>Nolan Lawson</em>, 2016-08-15</li>
<li><a href="https://www.npmjs.com/package/@rollup/plugin-typescript">@rollup/plugin-typescript</a>, 一个整合 Rollup 和 TypeScript 的官方插件</li>
</ol>
<a href="https://gitee.com/liuz2/liuz2/blob/master/content/posts/rollup-intro.md#tree_comm_title" class="no-underline db b--black pa2 tc bg-black-90" style="color:#eee;">进入留言</a><ul class="pa0">
  
   <li class="list dib">
     <a href="/tags/rollup" class="link f5 grow no-underline br-pill ba ph3 pv2 mb2 dib black sans-serif">rollup</a>
   </li>
  
</ul>
<div class="mt6 instapaper_ignoref">
      
      
      </div>
    </div>

    <aside class="w-30-l mt6-l"><div class="bg-light-gray pa3 nested-list-reset nested-copy-line-height nested-links">
    <p class="f5 b mb3">目录</p>
      <nav id="TableOfContents">
  <ul>
    <li><a href="#安装">安装</a></li>
    <li><a href="#快速上手">快速上手</a></li>
    <li><a href="#命令行接口">命令行接口</a>
      <ul>
        <li><a href="#配置文件">配置文件</a></li>
        <li><a href="#与-javascript-api-的差异">与 JavaScript API 的差异</a></li>
        <li><a href="#从-node-包加载配置文件">从 Node 包加载配置文件</a></li>
        <li><a href="#命令行标志">命令行标志</a></li>
        <li><a href="#从标准输入读取文件">从标准输入读取文件</a></li>
      </ul>
    </li>
    <li><a href="#javascript-api">JavaScript API</a>
      <ul>
        <li><a href="#rolluprollup">rollup.rollup</a></li>
        <li><a href="#rollupwatch">rollup.watch</a></li>
        <li><a href="#动态载入配置文件">动态载入配置文件</a></li>
      </ul>
    </li>
    <li><a href="#教程">教程</a>
      <ul>
        <li><a href="#使用输出插件">使用输出插件</a></li>
        <li><a href="#代码分割">代码分割</a></li>
      </ul>
    </li>
    <li><a href="#常用插件">常用插件</a></li>
    <li><a href="#ref">REF</a></li>
  </ul>
</nav>
  </div>




</aside>

  </article>

    </main>
    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
  <div class="flex justify-between">
  <a class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3" href="https://liuz2.gitee.io/" >
    &copy;  liuz2's Blog 2022 
  </a>
    <div>














</div>
  </div>
</footer>

    

  <script src="/dist/js/app.3fc0f988d21662902933.js"></script>


  </body>
</html>
